#include <mono/event/event_loop_thread.h>
#include <mono/common/scoped_lock.h>

namespace mono {
	
EventLoopThread::EventLoopThread(const ThreadInitCallback& cb, const std::string & name)
  : _loop(),
    _exiting(false), // FIXME: number it
    _mutex(),
    _cond(),
    _thread(name),
    _callback(cb)
{
}

EventLoopThread::~EventLoopThread()
{

}

EventLoopPtr EventLoopThread::start()
{
    assert(!_thread.isRunning());

    _thread.start(std::bind(&EventLoopThread::threadFunc, this));

    {
        mono::ScopedMutex lock(&_mutex);
        while (!_loop) {
            _cond.wait(&_mutex);
        }
    }

    return _loop;
}
void EventLoopThread::stop()
{
    if(_exiting) {
        return;
    }
    _exiting = true;
    mono::ScopedMutex lock(&_mutex);
    if (_loop) {
        _loop->quit();
        _loop.reset();
        _thread.join();  
    } 
}
void EventLoopThread::threadFunc()
{
    EventLoopPtr loop(new EventLoop());

    if (_callback) {
        _callback(loop);
    }

    {
        mono::ScopedMutex lock(&_mutex);
        _loop = loop;
        _cond.signal();
    }

    loop->loop();
  //assert(exiting_);
}

}
